﻿using DevExpress.LookAndFeel;
using DevExpress.Utils.Design;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Drawing;
using DevExpress.XtraEditors.Popup;
using DevExpress.XtraEditors.Registrator;
using DevExpress.XtraEditors.Repository;
using DevExpress.XtraEditors.ViewInfo;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors.Controls;
using XCI.Core;
using XCI.Extensions;
using XCI.Helper;

namespace XCI.Windows
{
    /// <summary>
    /// 下拉分页表格控件
    /// </summary>
    [DesignerCategory("Code")]
    [DefaultEvent("SelectedChanged")]
    public class PopupGridControlPagingEdit : PopupContainerEdit//, IAsyncBindingEditValue
    {
        #region Properties
        static PopupGridControlPagingEdit()
        {
            RepositoryItemPopupGridControlPagingEdit.RegisterPopupGridControlPagingEdit();
        }

        [Description("Gets settings specific to the current RepositoryItemPopupContainerEdit object.")]
        [DXCategory("Properties")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [SmartTagSearchNestedProperties]
        public new RepositoryItemPopupGridControlPagingEdit Properties => base.Properties as RepositoryItemPopupGridControlPagingEdit;

        public override string EditorTypeName => RepositoryItemPopupGridControlPagingEdit.CustomEditName;

        protected override PopupBaseForm CreatePopupForm()
        {
            if (Properties.PopupControl == null) return null;
            return new PopupGridControlPagingEditPopupForm(this);
        }
        #endregion

        #region 字段
        private readonly MutexStatus mutexStatus = new MutexStatus();
        private readonly OnceAction onceAction = new OnceAction();
        private const string loadDataOnceActionKey = "LoadData";
        private PopupContainerControl popupContainer;
        private SeparatorControl separator;
        private ButtonEdit filterEdit;
        private GridControlPlus gridControl;
        private GridViewPlus gridView;
        private GridControlStandardPaging standardPaging;
        private GridControlInfinitePaging infinitePaging;
        private EditorButton editClearButton;
        private EditorButton filterClearButton;
        private PropertyInfo displayMemberProperty;
        private PropertyInfo valueMemberProperty;
        private object currentValue;
        private string currentText;
        private int currentRowIndex = -1;
        private bool isEditBind;

        private object prveValue;
        #endregion

        #region 构造函数

        public PopupGridControlPagingEdit()
        {
            this.popupContainer = new DevExpress.XtraEditors.PopupContainerControl();
            this.filterEdit = new DevExpress.XtraEditors.ButtonEdit();
            this.gridControl = new XCI.Windows.GridControlPlus();
            this.gridView = new XCI.Windows.GridViewPlus();
            this.separator = new DevExpress.XtraEditors.SeparatorControl();
            this.standardPaging = new GridControlStandardPaging();
            this.infinitePaging = new GridControlInfinitePaging();

            // 
            // popupContainer
            // 
            this.popupContainer.Name = "popupContainer";
            this.popupContainer.TabIndex = 0;
            // 
            // filterEdit
            // 
            this.filterEdit.Dock = System.Windows.Forms.DockStyle.Top;
            this.filterEdit.Location = new System.Drawing.Point(0, 0);
            this.filterEdit.Name = "filterEdit";
            this.filterEdit.Properties.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
            this.filterEdit.Properties.EditValueChangedFiringMode = DevExpress.XtraEditors.Controls.EditValueChangedFiringMode.Buffered;
            this.filterEdit.TabIndex = 0;
            // 
            // gridControl
            // 
            this.gridControl.Id = this.Id;//$"popup-grid-{StringHelper.Guid()}";
            this.gridControl.Dock = System.Windows.Forms.DockStyle.Fill;
            this.gridControl.MainView = this.gridView;
            this.gridControl.Name = "gridControl";
            this.gridControl.TabIndex = 1;
            this.gridControl.ViewCollection.AddRange(new DevExpress.XtraGrid.Views.Base.BaseView[] {
            this.gridView});
            // 
            // gridView
            // 
            this.gridView.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
            this.gridView.GridControl = this.gridControl;
            this.gridView.Name = "gridView";
            this.gridView.OptionsBehavior.AutoPopulateColumns = false;
            this.gridView.OptionsView.ShowGroupPanel = false;

            // 
            // standardPaging
            // 
            standardPaging = new GridControlStandardPaging();
            standardPaging.Name = "standardPaging";
            standardPaging.Dock = DockStyle.Bottom;
            standardPaging.TabStop = false;
            standardPaging.Margin = new System.Windows.Forms.Padding(0);

            // 
            // infinitePaging
            // 
            infinitePaging = new GridControlInfinitePaging();
            infinitePaging.Name = "infinitePaging";
            infinitePaging.Dock = DockStyle.Bottom;
            infinitePaging.TabStop = false;
            infinitePaging.PageInfoPosition = PageInfoPositionEnum.Right;
            infinitePaging.Margin = new System.Windows.Forms.Padding(0);

            // 
            // separatorControl1
            // 
            this.separator.AutoSizeMode = true;
            this.separator.Dock = System.Windows.Forms.DockStyle.Top;
            this.separator.Name = "separatorControl1";
            this.separator.Padding = new System.Windows.Forms.Padding(0);
            this.separator.Size = new System.Drawing.Size(172, 1);
        }

        #endregion

        #region 公共属性

        /// <summary>
        /// 下拉表格弹出框默认宽度
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public static int DefaultPopupWidth { get; set; } = 600;

        /// <summary>
        /// 下拉表格弹出框默认高度
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public static int DefaultPopupHeight { get; set; } = 400;

        /// <summary>
        /// 表格Id
        /// </summary>
        [Category("XCI"), Description("表格ID")]
        public virtual string Id { get; set; } = $"popup-grid-{StringHelper.Guid()}";

        /// <summary>
        /// 指示要为此控件中的项显示的属性
        /// </summary>
        [Category("XCI"), Description("指示要为此控件中的项显示的属性")]
        [SmartTagProperty("DisplayMember", "XCI-Member", SmartTagActionType.RefreshBoundsAfterExecute)]
        public virtual string DisplayMember { get; set; }

        /// <summary>
        /// 指示用作控件中项的实际值的属性
        /// </summary>
        [Category("XCI"), Description("指示用作控件中项的实际值的属性")]
        [SmartTagProperty("ValueMember", "XCI-Member", SmartTagActionType.RefreshBoundsAfterExecute)]
        public virtual string ValueMember { get; set; }

        /// <summary>
        /// 确认选择方式
        /// </summary>
        [Category("XCI"), Description("确认选择方式"), DefaultValue(ConfirmMode.DoubleClick)]
        [SmartTagProperty("ConfirmSelectMode", "XCI", SmartTagActionType.RefreshBoundsAfterExecute)]
        public virtual ConfirmMode ConfirmSelectMode { get; set; } = ConfirmMode.DoubleClick;

        [Category("XCI"), Description("自动添加清除按钮"), DefaultValue(true)]
        [SmartTagProperty("AddClearButton", "XCI", SmartTagActionType.RefreshBoundsAfterExecute)]
        public virtual bool AddClearButton { get; set; } = true;


        [Category("XCI"), Description("选择完成后自动关闭下拉面板"), DefaultValue(true)]
        [SmartTagProperty("ConfirmSelectAutoClosePopup", "XCI", SmartTagActionType.RefreshBoundsAfterExecute)]
        public virtual bool ConfirmSelectAutoClosePopup { get; set; } = true;

        /// <summary>
        /// 显示分页控件
        /// </summary>
        [Category("XCI"), Description("显示分页控件"), DefaultValue(true)]
        [SmartTagProperty("ShowPaging", "XCI-Paging", SmartTagActionType.RefreshBoundsAfterExecute)]
        public virtual bool ShowPaging { get; set; } = true;

        /// <summary>
        /// 分页方式
        /// </summary>
        [Category("XCI"), Description("分页方式"), DefaultValue(PaginationMode.Infinite)]
        [SmartTagProperty("PagingMode", "XCI-Paging", SmartTagActionType.RefreshBoundsAfterExecute)]
        public virtual PaginationMode PagingMode { get; set; } = PaginationMode.Infinite;

        /// <summary>
        /// 分页大小
        /// </summary>
        [Category("XCI"), Description("分页大小"), DefaultValue(0)]
        [SmartTagProperty("PageSize", "XCI-Paging", SmartTagActionType.RefreshBoundsAfterExecute)]
        public virtual int PageSize { get; set; }

        #endregion

        #region 计算属性

        /// <summary>
        /// 集合成员数据类型
        /// </summary>
        [Browsable(false)]
        [DefaultValue(null)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual Type ModelType { get; set; }

        /// <summary>
        /// 选中行对象
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public object Selected { get; set; }

        /// <inheritdoc />
        public override object EditValue
        {
            get => base.EditValue;
            set
            {
                base.EditValue = value;
                if (value == null
                    || value == DBNull.Value
                    || string.IsNullOrEmpty(value.ToStringOrEmpty())
                    || Selected != null
                    || currentValue == value)
                {
                    return;
                }
                currentValue = value;
                _ = GetBindSelectedAsync(value);
            }
        }

        /// <inheritdoc />
        public override string Text
        {
            get => currentText;
            set
            {

            }
        }

        #endregion

        #region 控件

        /// <summary>
        /// 表格控件
        /// </summary>
        [Category("XCI"), Description("表格控件")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public GridControlPlus Grid => gridControl;

        /// <summary>
        /// 视图控件
        /// </summary>
        [Category("XCI"), Description("视图控件")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public GridViewPlus View => gridView;

        [Category("XCI"), Description("弹出窗体容器")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public PopupContainerControl PopupContainer => popupContainer;

        [Category("XCI"), Description("搜索框")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public ButtonEdit FilterEdit => filterEdit;

        [Category("XCI"), Description("分割线")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public SeparatorControl Separator => separator;

        [Category("XCI"), Description("标准分页控件")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public GridControlStandardPaging StandardPaging => standardPaging;

        [Category("XCI"), Description("滚动加载分页控件")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public GridControlInfinitePaging InfinitePaging => infinitePaging;
        #endregion

        #region 事件

        private static readonly object EventSelectedChanged = new object();
        private static readonly object EventLoadList = new object();
        private static readonly object EventLoadSingle = new object();

        [Category("XCI"), Description("选中项变化事件")]
        public virtual event EventHandler<PopupGridControlPagingSelectedEventArgs> SelectedChanged
        {
            add => Events.AddHandler(EventSelectedChanged, value);
            remove => Events.RemoveHandler(EventSelectedChanged, value);
        }

        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void OnSelectedChanged(PopupGridControlPagingSelectedEventArgs e)
        {
            var handler = (EventHandler<PopupGridControlPagingSelectedEventArgs>)Events[EventSelectedChanged];
            handler?.Invoke(this, e);
        }

        [Category("XCI"), Description("数据列表加载事件")]
        public virtual event EventHandler<PopupGridControlPagingLoadListEventArgs> LoadList
        {
            add => Events.AddHandler(EventLoadList, value);
            remove => Events.RemoveHandler(EventLoadList, value);
        }

        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void OnLoadList(PopupGridControlPagingLoadListEventArgs e)
        {
            var handler = (EventHandler<PopupGridControlPagingLoadListEventArgs>)Events[EventLoadList];
            handler?.Invoke(this, e);
        }

        [Category("XCI"), Description("单条数据加载事件")]
        public virtual event EventHandler<PopupGridControlPagingLoadSingleEventArgs> LoadSingle
        {
            add => Events.AddHandler(EventLoadSingle, value);
            remove => Events.RemoveHandler(EventLoadSingle, value);
        }

        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void OnLoadSingle(PopupGridControlPagingLoadSingleEventArgs e)
        {
            var handler = (EventHandler<PopupGridControlPagingLoadSingleEventArgs>)Events[EventLoadSingle];
            handler?.Invoke(this, e);
        }
        #endregion

        #region 初始化

        protected override void OnCreateControl()
        {
            base.OnCreateControl();
            if (WinFormHelper.IsDesignMode()) { return; }

            gridControl.Id = this.Id;
            gridControl.ModelType = ModelType;
            if (AddClearButton)
            {
                if (this.Properties.Buttons.All(p => p.Kind != ButtonPredefines.Clear))
                {
                    editClearButton = new EditorButton(ButtonPredefines.Clear) { Visible = false };
                    editClearButton.Click += async (o, e) => await ClearSelectedAsync();
                    this.Properties.Buttons.Add(editClearButton);
                }
            }

            filterEdit.Properties.Buttons.Clear();
            if (filterEdit.Properties.Buttons.All(p => p.Kind != ButtonPredefines.Clear))
            {
                filterClearButton = new EditorButton(ButtonPredefines.Clear) { Visible = false };
                filterClearButton.Click += async (o, e) => await ClearSelectedAsync();
                filterEdit.Properties.Buttons.Add(editClearButton);
            }

            if (this.Properties.PopupFormSize == Size.Empty)
            {
                var dpi = WinFormHelper.GetDpiRatio();
                if (this.Properties.PopupWidthMode == PopupWidthMode.UseEditorWidth)
                {
                    popupContainer.Size = new Size(Width, Convert.ToInt32(DefaultPopupHeight * dpi));
                }
                else
                {
                    popupContainer.Size = new Size(Convert.ToInt32(DefaultPopupWidth * dpi), Convert.ToInt32(DefaultPopupHeight * dpi));
                }
            }

            if (ConfirmSelectMode == ConfirmMode.Click)
            {
                gridView.RowClick += (o, e) =>
                {
                    if (e.RowHandle > -1 && e.Button == MouseButtons.Left) ConfirmSelectedAndClose();
                };
            }
            else
            {
                gridControl.RowDoubleClick += (o, e) => ConfirmSelectedAndClose();
            }

            this.popupContainer.Controls.Add(gridControl);
            if (PagingMode == PaginationMode.Paging)
            {
                standardPaging.TabStop = false;
                standardPaging.PageSize = PageSize;
                standardPaging.Size = new Size(infinitePaging.Size.Width, Convert.ToInt32(infinitePaging.Size.Height * WinFormHelper.GetDpiRatio()));
                this.popupContainer.Controls.Add(standardPaging);
                gridControl.PagingControl = standardPaging;
            }
            else if (PagingMode == PaginationMode.Infinite)
            {
                infinitePaging.TabStop = false;
                infinitePaging.PageSize = PageSize;
                infinitePaging.Size = new Size(infinitePaging.Size.Width, Convert.ToInt32(infinitePaging.Size.Height * WinFormHelper.GetDpiRatio()));
                this.popupContainer.Controls.Add(infinitePaging);
                gridControl.PagingControl = infinitePaging;
            }

            this.popupContainer.Controls.Add(separator);
            this.popupContainer.Controls.Add(filterEdit);

            this.Properties.PopupControl = popupContainer;
            this.Properties.ShowPopupCloseButton = false;
            this.Properties.PopupSizeable = false;

            this.QueryResultValue += PopupGridControlPagingEdit_QueryResultValue;
            this.QueryDisplayText += PopupGridControlPagingEdit_QueryDisplayText;
            this.QueryCloseUp += PopupGridControlPagingEdit_QueryCloseUp;
            this.Popup += PopupGridControlPagingEdit_Popup;

            this.filterEdit.EditValueChanged += FilterEdit_EditValueChanged;
            this.filterEdit.KeyDown += FilterEdit_KeyDown;

            this.gridControl.LoadData += GridControl_LoadData;
            this.gridControl.AfterInitialize += GridControl_AfterInitialize;
            this.gridControl.ProcessGridKey += GridControl_ProcessGridKey;

            this.gridView.SelectionChanged += GridView_SelectionChanged;
        }

        private void PopupGridControlPagingEdit_QueryCloseUp(object sender, CancelEventArgs e)
        {
            SetClearButtonVisible(editClearButton);
            SetClearButtonVisible(filterClearButton);
        }

        private void GridControl_LoadData(object sender, LoadDataEventArgs e)
        {
            if (isEditBind && Selected != null)
            {
                e.Task = () =>
                {
                    IPagingList pagingList = PopupGridControlPagingSingleList.From(Selected);
                    return Task.FromResult(pagingList);
                };
            }
            else
            {
                var args = new PopupGridControlPagingLoadListEventArgs();
                args.PageFilter = e.PageFilter;
                args.Key = filterEdit.Text?.Trim();
                OnLoadList(args);
                e.Task = args.Task;
            }
        }

        private async void GridControl_ProcessGridKey(object sender, KeyEventArgs e)
        {
            if (gridView.IsGroupRow(gridView.FocusedRowHandle)) return;

            if (e.KeyCode == Keys.Enter)
            {
                ConfirmSelectedAndClose();
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Delete)
            {
                await ClearSelectedAsync();
                e.Handled = true;
            }
            //else if (e.KeyCode == Keys.Up)
            //{
            //    gridView.MovePrev();
            //    e.Handled = true;
            //}
            //else if (e.KeyCode == Keys.Down)
            //{
            //    gridView.MoveNext();
            //    e.Handled = true;
            //}
            else if (e.KeyCode == Keys.Back)
            {
                if (Text.Length <= 0) return;
                filterEdit.Text = filterEdit.Text.Remove(filterEdit.Text.Length - 1);
                FocusFilterEditCore();
                e.Handled = true;
            }
            else if ((e.KeyValue >= 65 && e.KeyValue <= 90)//A-Z
                     || (e.KeyValue >= 97 && e.KeyValue <= 122)//a-z
                     || (e.KeyValue >= 48 && e.KeyValue <= 57))//0-9
            {
                filterEdit.Text += Convert.ToChar(e.KeyValue).ToString().ToLower();
                FocusFilterEditCore();
                e.Handled = true;
            }
        }

        private void GridView_SelectionChanged(object sender, DevExpress.Data.SelectionChangedEventArgs e)
        {
            if (gridView.SelectedRowsCount > 1)
            {
                gridView.ClearSelection();
                gridView.SelectRow(gridView.FocusedRowHandle);
            }
        }

        private void GridControl_AfterInitialize(object sender, EventArgs e)
        {
            gridView.PaintAppearance.HideSelectionRow.BackColor = gridView.PaintAppearance.FocusedRow.BackColor;
        }

        private async void PopupGridControlPagingEdit_Popup(object sender, EventArgs e)
        {
            await onceAction.RunAsync(loadDataOnceActionKey, async () =>
            {
                await gridControl.LoadFirstPageAsync();
                if (ShowPaging == false)
                {
                    if (PagingMode == PaginationMode.Paging)
                    {
                        standardPaging.Visible = false;
                    }
                    else if (PagingMode == PaginationMode.Infinite)
                    {
                        infinitePaging.Visible = false;
                    }
                }

            });
            //if (onceAction.Contains(loadDataOnceActionKey))
            //{
            //    SelectRowCore();
            //}
        }

        private void PopupGridControlPagingEdit_QueryResultValue(object sender, DevExpress.XtraEditors.Controls.QueryResultValueEventArgs e)
        {
            e.Value = GetValueMemberValue(Selected);
        }

        private void PopupGridControlPagingEdit_QueryDisplayText(object sender, DevExpress.XtraEditors.Controls.QueryDisplayTextEventArgs e)
        {
            if (e.EditValue == null || e.EditValue == DBNull.Value)
            {
                currentValue = null;
                currentText = string.Empty;
            }
            else if (!isEditBind && e.EditValue != currentValue && e.DisplayText != currentText && Selected != null)
            {
                currentValue = GetValueMemberValue(Selected);
                currentText = GetDisplayMemberValue(Selected);
            }
            else if (isEditBind && prveValue != currentValue && Selected != null)
            {
                currentValue = GetValueMemberValue(Selected);
                currentText = GetDisplayMemberValue(Selected);
                prveValue = currentValue;
            }

            e.DisplayText = currentText;
        }

        private async void FilterEdit_EditValueChanged(object sender, EventArgs e)
        {
            await gridControl.LoadFirstPageAsync();
        }

        private async void FilterEdit_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                ConfirmSelectedAndClose();
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Delete)
            {
                await ClearSelectedAsync();
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Up)
            {
                gridView.MovePrev();
                e.Handled = true;
            }
            else if (e.KeyCode == Keys.Down)
            {
                gridView.MoveNext();
                e.Handled = true;
            }
        }

        #endregion

        #region 方法

        private void SelectRowCore()
        {
            //if (currentRowIndex < 0)
            //{
            //    gridView.ClearSelection();
            //}
            if (currentRowIndex > 0 && gridView.FocusedRowHandle != currentRowIndex)
            {
                gridView.FocusedRowHandle = currentRowIndex;
                gridView.SelectRow(currentRowIndex);
            }
        }

        public async Task GetBindSelectedAsync(object value)
        {
            var args = new PopupGridControlPagingLoadSingleEventArgs { BindValue = value };
            OnLoadSingle(args);
            if (args.Task != null)
            {
                Selected = await args.Task.Invoke();
                isEditBind = true;
            }
            SetClearButtonVisible(editClearButton);
            SetClearButtonVisible(filterClearButton);
            onceAction.Remove(loadDataOnceActionKey);
        }

        protected void FocusFilterEditCore()
        {
            if (!filterEdit.Focused)
            {
                filterEdit.Focus();
                if (Text != null) filterEdit.SelectionStart = Text.Length;
            }
        }

        public void ConfirmSelectedAndClose()
        {
            ConfirmCore();
            if (ConfirmSelectAutoClosePopup)
            {
                ClosePopup();
            }
        }

        protected void ConfirmCore()
        {
            var args = GetSelectedEventArgs();
            Selected = args.Selected;
            currentRowIndex = gridView.FocusedRowHandle;

            OnSelectedChanged(args);
        }

        public async Task ClearSelectedAsync()
        {
            Selected = null;
            EditValue = null;
            isEditBind = false;
            await GetBindSelectedAsync(null);
        }

        private string GetDisplayMemberValue(object selected)
        {
            if (ModelType == null) throw new ArgumentException("请指定集合成员数据类型", nameof(ModelType));
            if (string.IsNullOrEmpty(DisplayMember)) throw new ArgumentException("DisplayMember不是有效的字段名称", nameof(DisplayMember));
            if (gridControl.ModelType == null) gridControl.ModelType = ModelType;

            if (displayMemberProperty == null) displayMemberProperty = ModelType.GetProperty(DisplayMember);
            return selected != null ? displayMemberProperty.GetValue(selected).ToStringOrEmpty() : null;
        }

        private object GetValueMemberValue(object selected)
        {
            if (ModelType == null) throw new ArgumentException("请指定集合成员数据类型", nameof(ModelType));
            if (string.IsNullOrEmpty(ValueMember)) throw new ArgumentException("ValueMember不是有效的字段名称", nameof(ValueMember));
            if (gridControl.ModelType == null) gridControl.ModelType = ModelType;

            if (valueMemberProperty == null) valueMemberProperty = ModelType.GetProperty(ValueMember);
            return selected != null ? valueMemberProperty.GetValue(selected) : null;
        }

        private PopupGridControlPagingSelectedEventArgs GetSelectedEventArgs()
        {
            var selected = gridControl.Selected;
            var args = new PopupGridControlPagingSelectedEventArgs();
            args.Selected = selected;
            args.Text = GetDisplayMemberValue(selected);
            args.Value = GetValueMemberValue(selected);
            return args;
        }

        private void SetClearButtonVisible(EditorButton edit)
        {
            if (edit == null) return;
            edit.Visible = Selected != null;
        }

        #endregion

        //#region Implementation of IAsyncBindingEditValue

        ///// <summary>
        ///// 异步绑定EditValue
        ///// </summary>
        ///// <returns>等待的任务</returns>
        //public async Task BindingEditValueAsync()
        //{
        //    await SetEditValueAsync(base.EditValue);
        //}

        //#endregion
    }

    [UserRepositoryItem("RegisterPopupGridControlPagingEdit")]
    public class RepositoryItemPopupGridControlPagingEdit : RepositoryItemPopupContainerEdit
    {
        static RepositoryItemPopupGridControlPagingEdit()
        {
            RegisterPopupGridControlPagingEdit();
        }

        public const string CustomEditName = "PopupGridControlPagingEdit";

        public override string EditorTypeName => CustomEditName;

        public static void RegisterPopupGridControlPagingEdit()
        {
            EditorRegistrationInfo.Default.Editors.Add(new EditorClassInfo(CustomEditName, typeof(PopupGridControlPagingEdit),
                typeof(RepositoryItemPopupGridControlPagingEdit), typeof(PopupGridControlPagingEditViewInfo), new PopupGridControlPagingEditPainter(), true, null));
        }

        public override void Assign(RepositoryItem item)
        {
            BeginUpdate();
            try
            {
                base.Assign(item);
                //RepositoryItemPopupGridControlPagingEdit source = item as RepositoryItemPopupGridControlPagingEdit;
                //if (source == null) return;
                ////
            }
            finally
            {
                EndUpdate();
            }
        }
    }

    public class PopupGridControlPagingEditViewInfo : PopupContainerEditViewInfo
    {
        public PopupGridControlPagingEditViewInfo(RepositoryItem item) : base(item)
        {
        }
    }

    public class PopupGridControlPagingEditPainter : ButtonEditPainter
    {

    }

    public class PopupGridControlPagingEditPopupForm : PopupContainerForm
    {
        public PopupGridControlPagingEditPopupForm(PopupGridControlPagingEdit ownerControlPagingEdit) : base(ownerControlPagingEdit)
        {
        }
    }

    public enum ConfirmMode
    {
        Click,
        DoubleClick
    }

    public enum PaginationMode
    {
        Paging,
        Infinite,
        None
    }

    public class PopupGridControlPagingSelectedEventArgs : EventArgs
    {
        public string Text { get; set; }
        public object Value { get; set; }
        public object Selected { get; set; }
    }

    public class PopupGridControlPagingLoadListEventArgs : EventArgs
    {
        public BasePageFilter PageFilter { get; set; }
        public string Key { get; set; }
        public Func<Task<IPagingList>> Task { get; set; }
    }

    public class PopupGridControlPagingLoadSingleEventArgs : EventArgs
    {
        public object BindValue { get; set; }
        public Func<Task<object>> Task { get; set; }
    }

    public class PopupGridControlPagingSingleList : IPagingList
    {
        private readonly List<object> list = new List<object>();

        public List<object> InnerList => list;

        public int GetPageIndex()
        {
            return 1;
        }

        public int GetPageSize()
        {
            return 10;
        }

        public IList GetRows()
        {
            return list;
        }

        public int GetTotal()
        {
            return GetRows().Count;
        }

        public static PopupGridControlPagingSingleList From(object bingRecord)
        {
            var singleList = new PopupGridControlPagingSingleList();
            singleList.InnerList.Add(bingRecord);
            return singleList;
        }
    }

    /*
    [System.ComponentModel.DesignerCategory("Code")]
    public class EnterprisePopupGridEdit : PopupGridControlPagingEdit
    {
        public override string ValueMember => "Id";
        public override string DisplayMember => "Name";
        public override Type ModelType => typeof(SysRole);

        protected override void OnLoadList(PopupGridControlPagingLoadListEventArgs e)
        {
            if (WinFormHelper.IsDesignMode()) return;
            var filter = new SysRoleFilter();
            filter.CombinePageFilter(e.PageFilter);
            filter.Key = e.Key;
            e.Task = async () => await SysRoleService.Instance.SelectPageListAsync(filter);
        }

        protected override void OnLoadSingle(PopupGridControlPagingLoadSingleEventArgs e)
        {
            if (WinFormHelper.IsDesignMode()) return;
            if (e.BindValue.IsEmpty()) return;
            e.Task = async () => await SysRoleService.Instance.SelectByIdAsync(e.BindValue.ToStringOrEmpty());
        }
    }
    */
}